"""
https://leetcode.cn/problems/binary-tree-maximum-path-sum/description/

124. 二叉树中的最大路径和
已解答
困难
相关标签
相关企业
二叉树中的 路径 被定义为一条节点序列，序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点，且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ，返回其 最大路径和 。

 

示例 1：


输入：root = [1,2,3]
输出：6
解释：最优路径是 2 -> 1 -> 3 ，路径和为 2 + 1 + 3 = 6
示例 2：


输入：root = [-10,9,20,null,null,15,7]
输出：42
解释：最优路径是 15 -> 20 -> 7 ，路径和为 15 + 20 + 7 = 42
 

提示：

树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000

"""
# Definition for a binary tree node.
from typing import Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    """
    基础仍是树的遍历
    只是添加一层动态规划的思想
    每个树节点记录一下，以当前节点为一个端点的情况下的最大和？
    遍历顺序为后序遍历，保证最后再对根节点进行结算

    针对每一个子树，维护两个值：子树内的最大长度(inner_max_len,最小为0)，与端点在根节点的最大长度(root_max_len,最小为0)。
    
    root_max_len(node)=max(node.val+max(root_max_len(node.left),root_max_len(node.right),0),0)

    temp_max_len=root_max_len(node.left)+root_max_len(node.right)+node.val
    inner_max_len(node)=max(inner_max_len(node.left),inner_max_len(node.right),temp_max_len)

    # 本算法与leetcode中的排名靠前的思想几乎完全一致，但速度就是差一些，此处不再优化

    """
    def maxPathSum(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        
        global_max_len=root.val
        def root_max_len(node):
            nonlocal global_max_len
            if not node:
                return 0
            left_root_max_len=root_max_len(node.left)
            right_root_max_len=root_max_len(node.right)
            temp_max_len=max(left_root_max_len,0)+max(right_root_max_len,0)+node.val
            global_max_len=max(global_max_len,temp_max_len)
            return node.val+max(left_root_max_len,right_root_max_len,0)
        
        root_max_len(root)

        return global_max_len

if __name__=='__main__':
    
    # root=TreeNode(-10,TreeNode(9),TreeNode(20,TreeNode(15),TreeNode(7)))
    root=TreeNode(-10)
    s=Solution()
    max_len=s.maxPathSum(root)
    print(max_len)
    pass